package uestc.lj.basicPromotion.bitoperation;

/**
 * 比较两个有符号整数，返回较大的那个
 * 要求不使用任何比较判断
 *
 * @Author:Crazlee
 * @Date:2021/11/28
 */
public class Code01_GetMax {
	/**
	 * 异或操作
	 *
	 * @param n 参数非0即1
	 * @return n的异或
	 */
	public static int flip(int n) {
		return n ^ 1;
	}

	/**
	 * 将n的最高位进行异或
	 * n是正数返回1
	 * n是负数返回0
	 *
	 * @param n 有符号整数
	 * @return n最高位的异或结果 n是正数返回1，n是负数返回0
	 */
	public static int sign(int n) {
		return flip((n >> 31) & 1);
	}

	/**
	 * 求a和b 的较大值
	 * 但是存在一个问题，a-b会存在溢出
	 *
	 * @param a 数a
	 * @param b 数b
	 * @return a和b的较大值
	 */
	public static int getMax1(int a, int b) {
		int c = a - b;
		/**
		 * 求a-b差值c的高位异或符号
		 * c>0,scA=1
		 * c<0,scA=0
		 */
		int scA = sign(c);
		/**
		 * scA=0,scB=1
		 * scA=1,scB=0
		 */
		int scB = flip(scA);

		//返回两个数的较大值
		return a * scA + b * scB;
	}

	public static int getMax2(int a, int b) {
		int c = a - b;
		int sa = sign(a);
		int sb = sign(b);
		int sc = sign(c);

		int difSab = sa ^ sb;
		int sameSab = flip(difSab);

		int returnA = difSab * sa + sameSab * sc;
		int returnB = flip(returnA);

		return a * returnA + b * returnB;
	}

	public static void main(String[] args) {
		int a = -16;
		int b = 1;
		System.out.println(getMax1(a, b));
		System.out.println(getMax2(a, b));
		a = 2147483647;
		b = -2147480000;
		System.out.println(getMax1(a, b)); // wrong answer because of overflow
		System.out.println(getMax2(a, b));

	}
}
